<template>
  <div id="map-container">
    <div id='info-container'>
      <div class="map-popup">
        <div class="popup-tit">
          <h3>查询结果</h3>
        </div>
        <div class="popup-con">
          <div class="identify-layer">
            图层：<select id="pop-identify-select" @change="layerSelect($event)">
              <option value="{{layer}}" v-for="(layer,meta) in querySourceLayers">{{layer}}</option>
            </select>
          </div>
          <div class="identify-content">
            <div style="position: relative; overflow: hidden; width: auto; height: 100%;">
              <div class="identify-table">
                <table>
                  <tbody>
                    <tr v-for="(key,value) in selectedPopLayer.properties">
                      <td class="item-name">{{key}}</td>
                      <td class="item-value">{{value}}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div id="map-status">
    <div style="position:absolute;right:15px;bottom:0;">
      <span v-if="zoom"> 级别：{{zoom}} </span>
      <span v-if="lng"> 经度：{{lng}} </span>
      <span v-if="lat"> 纬度：{{lat}} </span>
    </div>
  </div>
</template>


<script>
import mapboxgl from 'mapbox-gl/dist/mapbox-gl'
import { changeStyle } from '../store/action'
import { mapState } from 'vuex'
import { diff, validate} from 'mapbox-gl-style-spec'

let map

export default {
  props: {
    accessToken: {
      type: String,
      required: true
    }
  },

  computed: {
    ...mapState([
      'year',
      'theme'
    ])
  },
  methods:{
    getNewLayers:function(year,stacod){
      if(!stacod){
        var stacod = "隐藏";
      }
      var year_str = String(year);
      var timelineFilter = ["any",["all",["any",["==","h",0],["!has","h"]],["<=","vers",year_str]],["all",["==","h",1],["<=","vers_star",year],[">","vers_end",year]]];
      var incFilter = [];
      if(stacod=="所有"){
        incFilter= ["==","vers",year_str];
      }else{
        incFilter = ["all",["==","vers",year_str],["==","stacod",stacod]];
      }
      var layers = JSON.parse(JSON.stringify(this.layers));
      for(let i = 0;i < layers.length;i ++){
        if(layers[i].type==="background"){
          continue;
        }
        if(!layers[i].layout){layers[i].layout = {};}
        var finalFilter = [];
        var oldFilter = layers[i].filter;
        if(layers[i].source.indexOf("increase")!==-1&&stacod!=="隐藏"){
          if(oldFilter&&oldFilter.length>0){
            finalFilter = ["all",oldFilter,incFilter];
          }else{
            finalFilter = incFilter;
          }
        }else if(layers[i].source.indexOf("increase")!==-1&&stacod==="隐藏"){
          layers[i].layout["visibility"]="none";
        }else if(layers[i].source.indexOf("timeline")!==-1){
          if(oldFilter&&oldFilter.length>0){
            finalFilter = ["all",oldFilter,timelineFilter];
          }else{
            finalFilter = timelineFilter;
          }
          layers[i].filter = finalFilter;
          layers[i].layout["visibility"] = "visible";
        }
      }
      return layers;
    },
    mapClick: function(e){//地图点击时进行i查询，获得当前要素及属性，并显示i查询窗口
      var clickBuffer = 2;
      var southWest = {x:e.point.x-clickBuffer,y:e.point.y+clickBuffer};//查询缓冲区范围
      var northEast = {x:e.point.x+clickBuffer,y:e.point.y-clickBuffer};//查询缓冲区范围
      var features = map.queryRenderedFeatures([southWest,northEast]);//查询要素
      this.querySourceLayers = {};
      this.selectedPopLayer.properties = {};
      this.selectedPopLayer.length = 0;
      var sourceLayers = {};
      if(features.length===0){
        infoContainer.style.display = 'none';
        return;
      }
      for(let i=0;i<features.length;i++){
        var sourceLayer = features[i].layer["source-layer"];
        var properties = features[i].properties;
        var type = features[i].geometry.type;
        if(sourceLayer&&!sourceLayers[sourceLayer]){
          sourceLayers[sourceLayer]={
            type:type,
            properties:properties
          }
        }
      }
      this.querySourceLayers = sourceLayers;
      if(Object.keys(this.querySourceLayers).length>0){
        var i = 0;
        for(var layer in this.querySourceLayers){
          if(i === 0){
            $("#pop-identify-select").val(layer);
            this.selectedPopLayer.properties = this.querySourceLayers[layer].properties;
            this.selectedPopLayer.length = Object.keys(this.querySourceLayers[layer].properties).length;
            i++;
          }
        }
        if(this.popup.isOpen&&this.popup.isOpen()){
          this.popup.setLngLat(map.unproject(e.point));
        }else if(this.popup.isOpen&&!this.popup.isOpen()){
          this.popup.setLngLat(map.unproject(e.point)).addTo(map);
        }else{
          var infoContainer = document.getElementById('info-container');
          var popup = new mapboxgl.Popup({closeOnClick:false,offset:10})
            .setLngLat(map.unproject(e.point))
            .setDOMContent(infoContainer)
            .addTo(map);
          this.popup = popup;
          infoContainer.style.display = 'block';
          //this.popup.on("close",this.popupClosed);
        }
        /*infoContainer.style.left = e.point.x-155 + 'px';
        var h = (this.selectedPopLayer.length)*27+16;
        if(h>300){h = 300;}
        infoContainer.style.top = e.point.y-87-h+'px';*/
      }
    },
    mapLoaded:function(e){//地图加载完成后，获得当前地图级别和经纬度
      this.zoom = map.getZoom().toFixed(4);
      var center = map.getCenter();
      this.lng = center.lng.toFixed(4);
      this.lat = center.lat.toFixed(4);
    },
    mapZoom:function(e){//缩放地图时更新当前级别和经纬度，当级别大于12时，显示时态控制工具条
      var center = map.getCenter();
      var zoom = map.getZoom();
      this.zoom = zoom.toFixed(4);
      
      this.lng = center.lng.toFixed(4);
      this.lat = center.lat.toFixed(4);
      if(zoom>=12){
        $(".toolbar").fadeIn(200);
        $(".sidebar").fadeIn(200);
      }else{
        $(".toolbar").fadeOut(200);
        $(".sidebar").fadeOut(200);
      }
      
    },
    mapDrag:function(e){//拖拽地图时更新当前经纬度
      var center = map.getCenter();
      this.lng = center.lng.toFixed(4);
      this.lat = center.lat.toFixed(4);
    },
    layerSelect: function(e){//在i查询窗口中切换图层
      var infoContainer = document.getElementById('info-container');
      var oldHeight = infoContainer.offsetHeight;
      var layerName = e.target.value;
      if(Object.keys(this.querySourceLayers).length>0){
        for(var layer in this.querySourceLayers){
          if(layer === layerName){
            this.selectedPopLayer.properties = this.querySourceLayers[layer].properties;
            this.selectedPopLayer.length = Object.keys(this.querySourceLayers[layer].properties).length;
            break;
          }
        }
      }
      var h = (this.selectedPopLayer.length)*27+16;
      if(h>300){h = 300;}
      var newHeight = h+87;
      var c = newHeight - oldHeight;
      infoContainer.style.top = Number(infoContainer.style.top.split('px')[0]) - c + 'px' ;
    },
    closeInfoContainer: function(){//关闭i查询窗口
      $("#info-container").hide();
    },
    parseUrl:function(url) {  //解析url，获取url参数
      var a =  document.createElement('a');  
      a.href = url;  
      return {  
        source: url,  
        protocol: a.protocol.replace(':',''),  
        host: a.hostname,  
        port: a.port,  
        query: a.search,  
        params: (function(){  
          var ret = {},  
          seg = a.search.replace(/^\?/,'').split('&'),  
          len = seg.length, i = 0, s;  
          for (;i<len;i++) {  
              if (!seg[i]) { continue; }  
              s = seg[i].split('=');  
              ret[s[0]] = s[1];  
          }  
          return ret;  
        })(),  
        file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],  
        hash: a.hash.replace('#',''),  
        path: a.pathname.replace(/^([^\/])/,'/$1'),  
        relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1],  
        segments: a.pathname.replace(/^\//,'').split('/')  
      };  
    }
  },
  ready () {
    var that = this;
    $.getJSON("./static/style.json",function(data){//从服务器获取地图的stylejson样式
      var initStyle = JSON.parse(JSON.stringify(data));
      that.$dispatch("broadcast-style",initStyle);
      //that.$store.commit('PATCH_STYLE', initStyle);
      that.layers = JSON.parse(JSON.stringify(initStyle.layers));//获取原始的图层列表
      initStyle.layers = that.getNewLayers(2015,"隐藏");//过滤2015年的图层
      var options = {
        container:"map-container",
        attributionControl: false,
        style:initStyle,
        center: [116.3181, 39.59104],
        zoom: 11
      };
      mapboxgl.accessToken = that.accessToken;
      map = new mapboxgl.Map(options)
      map.on("click",that.mapClick)
      map.on("load",that.mapLoaded)
      map.on("zoom",that.mapZoom)
      map.on("drag",that.mapDrag)
      map.addControl(new mapboxgl.NavigationControl(), 'bottom-right')
      map.addControl(new mapboxgl.ScaleControl({unit: 'metric'}))
      var href = window.location.href.replace("/#!","");//解析url参数
      var params = that.parseUrl(href).params;
      var bbox = params.bbox;
      if(bbox){//缩放到url指定的bbox
        var bounds = bbox.split(",");
        map.fitBounds([[Number(bounds[0]),Number(bounds[1])],[Number(bounds[2]),Number(bounds[3])]],{linear:true,maxzoom:14});
      }
    });
  },
  data(){
    return {
      layers:[],
      querySourceLayers: {},
      selectedPopLayer:{
        properties:{},
        length:0
      },
      zoom:"",
      lng:"",
      lat:"",
      popup:{}
    }
  },
  events:{
    'map-bounds-change':function(params) {
      var bounds = params.bounds;
      map.fitBounds(bounds);
    },
    'style-change':function(style){
      if(!map||!map.setStyle){
        return;
      }
      var oldStyle = map.getStyle();
      var comds = diff(oldStyle,style);
      for(var i=0,length=comds.length;i<length;i++){
        switch(comds[i].command){
          case 'setPaintProperty':
            map.setPaintProperty.apply(map,comds[i].args);
            break;
          case 'setLayoutProperty':
            map.setLayoutProperty.apply(map,comds[i].args);
            break;
          case 'setStyle':
            map.setStyle.apply(map,comds[i].args);
            break;
          case 'addLayer':
            map.addLayer.apply(map,comds[i].args);
            break;
          case 'removeLayer':
            map.removeLayer.apply(map,comds[i].args);
            break;
          case 'setFilter':
            map.setFilter.apply(map,comds[i].args);
            break;
          case 'setLayerZoomRange':
            map.setLayerZoomRange.apply(map,comds[i].args);
            break;
          case 'addSource':
            map.addSource.apply(map,comds[i].args);
            break;
          case 'removeSource':
            map.removeSource.apply(map,comds[i].args);
            break;
        }
      }
    }
  },
  watch: {
    'year + theme': function () {
      var stacod = this.theme||"所有";
      var year_str = String(this.year);
      //分两种情况筛选（两种情况取并集）：
      //1、h=0或者h不存在，则数据属于现势库，应筛选vers<=year；
      //2、h=1，则数据属于历史库，应筛选vers_star<=year且vers_end>year。
      var timelineFilter = ["any",["all",["any",["==","h",0],["!has","h"]],["<=","vers",year_str]],["all",["==","h",1],["<=","vers_star",this.year],[">","vers_end",this.year]]];
      var incFilter = [];
      if(stacod==="所有"){
        incFilter = ["==","vers",year_str];
      }else if(stacod!=="隐藏"){
        incFilter = ["all",["==","vers",year_str],["==","stacod",stacod]];
      }
      var layers = JSON.parse(JSON.stringify(this.layers));
      for(let i = 0;i < layers.length;i++){
        if(layers[i].type==='background'){
          continue;
        }
        var finalFilter = [];
        var oldFilter = layers[i].filter;
        if(layers[i].source.indexOf("increase")!==-1&&stacod!=="隐藏"){//增量，显示
          if(oldFilter&&oldFilter.length>0){
            finalFilter = ["all",oldFilter,incFilter];
          }else{
            finalFilter = incFilter;
          }
          map.setFilter(layers[i].id,finalFilter);
          map.setLayoutProperty(layers[i].id,"visibility","visible");
        }else if(layers[i].source.indexOf("increase")!==-1&&stacod==="隐藏"){//增量，隐藏
          map.setLayoutProperty(layers[i].id, 'visibility', 'none');
        }else if(layers[i].source.indexOf("timeline")!==-1){//时空数据
          if(oldFilter&&oldFilter.length>0){
            finalFilter = ["all",oldFilter,timelineFilter];
          }else{
            finalFilter = timelineFilter;
          }
          map.setFilter(layers[i].id,finalFilter);
          map.setLayoutProperty(layers[i].id,"visibility","visible");
        }
      }
    }
  },
  style: {
    handler(style,oldStyle){
      if(!map.setStyle){
        return;
      }
      var comds = diff(oldStyle,style);
      for(var i=0,length=comds.length;i<length;i++){
        switch(comds[i].command){
          case 'setPaintProperty':
            map.setPaintProperty.apply(map,comds[i].args);
            break;
          case 'setLayoutProperty':
            map.setLayoutProperty.apply(map,comds[i].args);
            break;
          case 'setStyle':
            map.setStyle.apply(map,comds[i].args);
            break;
          case 'addLayer':
            map.addLayer.apply(map,comds[i].args);
            break;
          case 'removeLayer':
            map.removeLayer.apply(map,comds[i].args);
            break;
          case 'setFilter':
            map.setFilter.apply(map,comds[i].args);
            break;
          case 'setLayerZoomRange':
            map.setLayerZoomRange.apply(map,comds[i].args);
            break;
          case 'addSource':
            map.addSource.apply(map,comds[i].args);
            break;
          case 'removeSource':
            map.removeSource.apply(map,comds[i].args);
            break;
        }
      }
    },
    deep: true
  }
}
</script>


<style scoped>
#map-container {
  position: absolute;
  right: 0;
  bottom: 20px;
  top: 0;
  left: 0;
}
#map-status {
  position: absolute;
  bottom: 0;
  height: 20px;
  width: 100%;
  background-color: #dcdcdc;
}

/******************图层弹框样式*******************************/
#info-container {
  display: none;
  /*position: absolute;
  left: 500px;
  top: 300px;
  z-index: 1;
  -webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,.6));
  -moz-filter: drop-shadow(0 1px 4px rgba(0,0,0,.6));
  -ms-filter: drop-shadow(0 1px 4px rgba(0,0,0,.6));
  -o-filter: drop-shadow(0 1px 4px rgba(0,0,0,.6));
  filter: drop-shadow(0 1px 4px rgba(0,0,0,.6));
  height: auto;
  width: auto;*/
}

#info-tip {
  width: 0;
  height: 0;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-top: 7px solid white;
  margin: 0 auto;
}

.map-popup {
  width: 310px;
  cursor: default;
}

.popup-tit {
  height: 30px;
  line-height: 30px;
  border-bottom: 1px solid #eee;
  padding: 0 10px;
  position: relative;
  width: auto;
  border-color: #ccc;
  background-color: #e9f1f9;
}
.popup-tit h3 {
  font-size: 14px;
  margin:0;
}
.popup-con {
  position: relative;
  padding: 10px;
  background-color: #fff;
}
.identify-layer {
  height: 24px;
  margin: 6px 0 0 10px;
}
.identify-layer select {
  width: 210px;
  height: 24px;
  line-height: 24px;
  font-weight: bold;
  color: #478edd;
  margin-left: 6px;
}
.identify-content {
  padding: 8px;
  max-height: 200px;
  overflow: auto;
}
.identify-table {
  float: right;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  width: 100%;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
  padding: 0;
  width: 100%;
}
.identify-table .item-name {
  width: 120px;
  word-break: break-all;
  padding: 3px;
  background-color: #c6deff;
}
.identify-table td {
  border: 1px solid #ccc;
}
.identify-table .item-value {
  word-break: break-all;
  padding: 3px;
}
#close-info {
  position: absolute;
  top: 5px;
  right: 5px;
  font-size: 14px;
  cursor: pointer;
}
</style>
